<?php
declare(strict_types=1);

namespace App\Service;

use App\Constants\SettleAccessType;
use App\Constants\XZXResponseCode;
use App\Exception\XZXValidationException;
use App\Model\Dao\TradeOrderDetailDao;
use App\Model\Dao\TradeOrderLogDao;
use App\Model\Dao\TradeOrderThawDao;
use App\Model\Enum\OrderTransTypeEnum;
use App\Model\Enum\StatusEnum;
use App\Utils\CustomUtils;
use Hyperf\DbConnection\Db;
use Hyperf\Di\Annotation\Inject;

class TradeOrderThawService
{
    /**
     * @Inject()
     * @var TradeOrderThawDao
     */
    private $TradeOrderThawDao;

    /**
     * @Inject()
     * @var TradeOrderDetailDao
     */
    private $TradeOrderDetailDao;

    /**
     * @var TradeOrderLogDao
     * @Inject()
     */
    protected $TradeOrderLogDao;

    /**
     * @Inject()
     * @var SettleService
     */
    private $SettleService;

    public function add($param)
    {
        $data = $this->checkParam($param);

        Db::beginTransaction();
        try {
            // 写表
            $this->TradeOrderThawDao->insert($data);

            $this->TradeOrderDetailDao->update($data['orderId'], [
                'isThaw'    => 1,
            ]);
        } catch (\Throwable $th) {
            CustomUtils::xzxDebug($th->getMessage());
            Db::rollBack();
            throw new XZXValidationException(XZXResponseCode::getMessage(XZXResponseCode::ADD_FAIL));
        }

        Db::commit();

        // 写队列，解冻单结算
        $this->SettleService->addMq($data['mchId'], [
            "accessType"    => SettleAccessType::ACCESS_TYPE_TRADE_ORDER_THAW,
            "thawId"        => $data['id'],
            "handleStatus"  => 0
        ]);

        $this->addOrderLog([$data]);

        return CustomUtils::xeServiceReturnData(XZXResponseCode::SUCCESS_CODE,XZXResponseCode::getMessage(XZXResponseCode::SUCCESS_CODE),CustomUtils::xzxEmptyObject());
    }

    /**
     * @param array $param
     * @return array
     * 校验参数
     */
    private function checkParam (array $param) {
        // 订单
        $detail = $this->TradeOrderDetailDao->getByTradeNo($param['tradeNo']);
        $isThaw = $this->TradeOrderThawDao->getByTradeNo($param['tradeNo']);
        if (empty($detail)) {
            throw new XZXValidationException(XZXResponseCode::getMessage(XZXResponseCode::DATA_NOT_FOUND));
        }

        if($param['source'] == 2 && !$param['isSuperRole']){
            if(!in_array($detail['mchId'],$param['mchIdList'])){
                throw new XZXValidationException(XZXResponseCode::getMessage(XZXResponseCode::NO_PERMISSION_TO_OPERATE));
            }
        }             

        // 未结算不能操作
        if ($detail['isSettle'] != 2) {
            throw new XZXValidationException(XZXResponseCode::getMessage(XZXResponseCode::NO_SETTLEMENT));
        }

        // 已经发起拒付不能操作
        if ($detail['isDis'] == 1 || $detail['isDis'] == 2) {
            throw new XZXValidationException(XZXResponseCode::getMessage(XZXResponseCode::REFUSING_ORDER));
        }

        // 已经拒付
        if ($detail['isDis'] == 4) {
            throw new XZXValidationException(XZXResponseCode::getMessage(XZXResponseCode::REFUSED_ORDER));
        }

        // 未冻结不能操作
        if ($detail['isFrozen'] != 4) {
            throw new XZXValidationException(XZXResponseCode::getMessage(XZXResponseCode::NO_FROZENED_ORDER));
        }

        // 已经发起退款不能操作
        if ($detail['isRefund'] == 1 || $detail['isRefund'] == 2) {
            throw new XZXValidationException(XZXResponseCode::getMessage(XZXResponseCode::REFUNDING_ORDER));
        }

        // 已经退款不能操作
        if ($detail['isRefund'] == 4) {
            throw new XZXValidationException(XZXResponseCode::getMessage(XZXResponseCode::REFUNDED_ORDER));
        }

        // 已经发起解冻不能操作
        if ($detail['isThaw'] == 1 || $detail['isThaw'] == 2 || (!empty($isThaw) && $isThaw['handleStatus'] == 0)  || (!empty($isThaw) && $isThaw['handleStatus'] == 1)) {
            throw new XZXValidationException(XZXResponseCode::getMessage(XZXResponseCode::THAWING_ORDER));
        }

        $data['id']            = CustomUtils::createUUID();
        $data['orderId']       = $detail['id'];
        $data['mchId']         = $detail['mchId'];
        $data['mchNo']         = $detail['mchNo'];
        $data['transCurrency'] = $detail['mchTransCurrency'];
        $data['transAmount']   = $detail['mchTransAmount'];
        $data['tradeNo']       = $detail['tradeNo'];
        $data['tradeNewNo']    = CustomUtils::createTradeNo('thaw');
        $data['handleStatus']  = 0;
        $data['transReason']   = $param['transReason'];
        $data['createBy']      = $param['createBy'];

        // 结算金额和币种
        $data["transSettleCurrency"] = $detail["settleCurrency"];
        $data["transSettleAmount"]   = $detail["settleAmount"];

        return $data;
    }

    /**
     * 写入交易变更日志
     *
     * @param array $orderList
     */
    public function addOrderLog ($orderList = []) {

        $logList = [];

        foreach ($orderList as $order) {
            $log = [
                'id'                => CustomUtils::createUUID(),
                'transId'           => $order['id'],
                'mchId'             => $order['mchId'],
                'mchNo'             => $order['mchNo'],
                'orderId'           => $order['orderId'],
                'tradeNo'           => $order['tradeNo'],
                'tradeNewNo'        => $order['tradeNewNo'],
                'transType'         => OrderTransTypeEnum::THAW,
                'transCurrency'     => $order['transCurrency'],
                'transAmount'       => $order['transAmount'],
                'transReason'       => $order['transReason'],
                'handleStatus'      => $order['handleStatus'],
                'status'            => StatusEnum::ON,
                'createTime'        => time(),
                'createBy'          => $order['createBy']
            ];

            array_push($logList, $log);
        }

        $this->TradeOrderLogDao->insert($logList);
    }

}
